package tp.pr2;

/**
 * A street links two places A and B in one direction. If it is defined as
 * Street(A,NORTH,B) it means that Place B is at NORTH of Place A. Streets are
 * two-way streets, i.e. if B is at NORTH of A then A is at SOUTH of B. Some
 * streets are closed and a code (contained in a code card) is needed to open
 * them
 */
public class Street {
	private Place source;
	private Direction direction;
	private Place target;
	private boolean isOpen;
	private String code;

	/**
	 * Creates an open street and it have not any code to open or close it
	 * 
	 * @param source
	 *            - lugar de origen (A en el ejemplo) direction - representa
	 *            como esta el lugar de destino respecto del lugar origen target
	 *            - lugar de destino (B)
	 * 
	 */
	public Street(Place source, Direction direction, Place target) {
		this.source = source;
		this.direction = direction;
		this.target = target;
		this.isOpen = true;
		this.code = null;
	}

	/**
	 * Creates a street that has a code to open and close it
	 * 
	 * @param source
	 *            - Source place
	 * @param direction
	 *            - Represents how is placed the target place with respect to
	 *            the source place
	 * @param target
	 *            - Target place
	 * @param isOpen
	 *            - Determines is the street is opened or closed
	 * @param code
	 *            - The code that opens and closes the street
	 */
	public Street(Place source, Direction direction, Place target,
			boolean isOpen, java.lang.String code) {
		this.source = source;
		this.direction = direction;
		this.target = target;
		this.isOpen = isOpen;
		this.code = code;
	}

	/**
	 * Comprueba si la calle viene desde un lugar en una direccion dada
	 * (recuerda que las calles tienen dos sentidos)
	 * 
	 * @return true si la calle viene desde el input place
	 */
	public boolean comeOutFrom(Place place, Direction whichDirection) {
		boolean ret = false;
		// if (source.toString().equals(place.toString())
		// && direction.equals(whichDirection))
		// ret = true;
		// else if (target.toString().equals(place.toString())
		// && direction.equals(whichDirection.opposite()))
		// ret = true;
		// return ret;
		if (source.equals(place) && direction.equals(whichDirection))
			ret = true;
		else if (target.equals(place)
				&& direction.equals(whichDirection.opposite()))
			ret = true;
		return ret;
	}

	/**
	 * Devuelve el lugar al otro lado de la calle desde el lugar en el que estoy
	 */
	public Place nextPlace(Place place) {
		Place ret = null;
		if (place == source)
			ret = target;
		else if (place == target)
			ret = source;
		return ret;
	}

	/**
	 * Checks if the street is open or closed
	 * 
	 * @return true, if the street is open, and false when the street is closed
	 */
	public boolean isOpen() {
		return isOpen;
	}

	/**
	 * Tries to open a street using a code card. Codes must match in order to
	 * complete this action
	 * 
	 * @param card
	 *            - A code card to open the street
	 * @return true if the action has been completed
	 */
	public boolean open(CodeCard card) {
		if (this.code == card.getCode()) {
			isOpen = true;
			return true;
		}
		return false;
	}

	/**
	 * Tries to close a street using a code card. Codes must match in order to
	 * complete this action
	 * 
	 * @param card
	 *            - A code card to open the street
	 * @return true if the action has been completed
	 */
	public boolean close(CodeCard card) {
		if (this.code == card.getCode()) {
			isOpen = false;
			return true;
		}
		return false;
	}
}